﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

using WpfApp4.Models;
using WpfApp4.Models.Config;
using WpfApp4.Utilities;

using XEvent;
using XEvent.Events;
using XEvent.UI;

using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace WpfApp4.ViewModels
{
    public class SettingWindowViewModel : ViewModelBase
    {
        private WindowEvent _windowEvent;

        public SettingWindowViewModel()
        {
            _windowEvent = XEventAgent.Instance.EventManager.GetEvent<WindowEvent>();

            Init();
        }

        private void Init()
        {
            var configs = MenuInfo.Instance.MenuItems;

            CurrentMenu = new MenuConfig();
            CurrentMenu.MenuItems = configs;

            UpdateMenuList();
        }

        public ObservableCollection<MenuConfig> MenuConfigCollection { get; private set; } = new ObservableCollection<MenuConfig>();

        private bool isSub = false;


        private MenuConfig _selectedMenu;
        public MenuConfig SelectedMenu
        {
            get => _selectedMenu;
            set
            {
                SetProperty(ref _selectedMenu, value);
                CheckSubMenuVisible = _selectedMenu != null ? _selectedMenu.MenuItems.Length > 0 ? Visibility.Visible : Visibility.Collapsed : Visibility.Collapsed;
            }
        }


        private MenuConfig _currentMenu;
        public MenuConfig CurrentMenu { get => _currentMenu; set => SetProperty(ref _currentMenu, value); }


        private Stack<MenuConfig> menuStack = new Stack<MenuConfig>();


        private MenuConfig newMenu;
        public MenuConfig NewMenu { get => newMenu; set => SetProperty(ref newMenu, value); }


        private Visibility _addVisible = Visibility.Collapsed;
        public Visibility AddVisible { get => _addVisible; set => SetProperty(ref _addVisible, value); }


        private Visibility _mainVisible = Visibility.Collapsed;
        public Visibility MainVisible { get => _mainVisible; set => SetProperty(ref _mainVisible, value); }


        private Visibility _checkSubMenuVisible;
        public Visibility CheckSubMenuVisible { get => _checkSubMenuVisible; set => SetProperty(ref _checkSubMenuVisible, value); }


        public ICommand SelectedChangeCommand
        {
            get => new RelayCommand<MenuConfig>(obj =>
            {
                if (obj != null)
                {
                    SelectedMenu = obj;
                    MainVisible = Visibility.Visible;
                    //CheckSubMenuVisible = SelectedMenu.MenuItems.Length > 0 ? Visibility.Visible : Visibility.Collapsed;
                }
            });
        }

        public ICommand SettingMenuCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                menuStack.Push(CurrentMenu);

                CurrentMenu = SelectedMenu;
                SelectedMenu = null;

                UpdateMenuList();
                MainVisible = Visibility.Collapsed;
            });
        }

        public ICommand AddMenuCommand
        {
            get => new RelayCommand<string>(sub =>
            {
                AddVisible = Visibility.Visible;
                NewMenu = new MenuConfig
                {
                    Name = "",
                    Command = "",
                    CommandParameter = "",
                    WindowSize = "",
                };

                isSub = sub == "True";
            });
        }

        public ICommand BackLastMenuCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                if (menuStack.Count <= 0) return;

                CurrentMenu = menuStack.Pop();
                UpdateMenuList();

                SelectedMenu = null;
                //CheckSubMenuVisible = Visibility.Collapsed;
                MainVisible = Visibility.Collapsed;
            });
        }

        public ICommand ConfirmCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                if(string.IsNullOrWhiteSpace(NewMenu.Name)) return;

                NewMenu.Id = Guid.NewGuid().ToString();
                NewMenu.MenuItems = new MenuConfig[] { };

                if (isSub)
                {
                    var tempList = SelectedMenu.MenuItems.ToList();
                    tempList.Add(NewMenu);
                    SelectedMenu.MenuItems = tempList.ToArray();
                    CheckSubMenuVisible = SelectedMenu.MenuItems.Length > 0 ? Visibility.Visible : Visibility.Collapsed;
                }
                else
                {
                    var tempList = CurrentMenu.MenuItems.ToList();
                    tempList.Add(NewMenu);
                    CurrentMenu.MenuItems = tempList.ToArray();
                }

                AddVisible = Visibility.Collapsed;
                UpdateMenuList();
            });
        }

        public ICommand CancelCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                AddVisible = Visibility.Collapsed;
            });
        }



        public ICommand SaveCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                while (menuStack.Count > 0)
                {
                    BackLastMenuCommand.Execute(null);
                }

                MenuInfo.Instance.MenuItems = CurrentMenu.MenuItems;
                ConfigManager.SaveConfig();

                _windowEvent.Publish(new WindowEvent
                {
                    Type = EventType.Action,
                    WindowActionType = WindowActionType.Close,
                    EventId = EventId.SettingWindow,
                });
            });
        }

        public ICommand DeletedCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                if (MenuConfigCollection.Remove(SelectedMenu))
                {
                    SelectedMenu = null;
                    //CheckSubMenuVisible = Visibility.Collapsed;
                    CurrentMenu.MenuItems = MenuConfigCollection.ToArray();
                }
            });
        }

        public ICommand MoveCommand
        {
            get => new RelayCommand<string>(obj =>
            {
                switch (obj)
                {
                    case "Up":
                        MoveUp();
                        break;
                    case "Down":
                        MoveDown();
                        break;
                }

                CurrentMenu.MenuItems = MenuConfigCollection.ToArray();
            });
        }

        private void MoveUp()
        {
            int index = MenuConfigCollection.IndexOf(SelectedMenu);
            if (index > 0)
            {
                MenuConfigCollection.RemoveAt(index);
                index--;
                MenuConfigCollection.Insert(index, SelectedMenu);
            }
        }

        private void MoveDown()
        {
            int index = MenuConfigCollection.IndexOf(SelectedMenu);
            if (index < MenuConfigCollection.Count - 1)
            {
                MenuConfigCollection.RemoveAt(index);
                index++;
                MenuConfigCollection.Insert(index, SelectedMenu);
            }
        }


        private void UpdateMenuList()
        {
            MenuConfigCollection.Clear();
            foreach (var item in CurrentMenu.MenuItems)
            {
                MenuConfigCollection.Add(item);
            }
        }

    }
}
